home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / RandomDot 1.1.0 / headers / RandomDot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  4.4 KB  |  166 lines  |  [TEXT/KAHL]

  1. /* RandomDot.c
  2.     by David Phillip Oster October 1994 oster@netcom.com
  3.     for:
  4.     Stuart Inglis singlis@waikato.ac.nz
  5.     Department of Computer Science
  6.     University of Waikato, Hamilton, New Zealand
  7.  */
  8. #include "RandomDotMain.h"
  9. #include "RandomDotRes.h"
  10.  
  11. #include "RandomDot.h"
  12. #include "Progress.h"
  13. #include "Utils.h"
  14.  
  15. #define round(X)    ((int) ((X) + 0.5))
  16. #define DPI            72                /* assume 72 pixels per inch */
  17. #define    E            round(2.5*DPI)    /* eye separation is assumed to be 2.5 inches */
  18. #define mu            (1/3.0)            /* depth of field (fraction of viewing dist.) */
  19. #define separation(Z)    round((1-mu*Z)*E/(2-mu*Z))    /* stereo sep corresponding to position z */
  20. #define farPlane    separation(0)    /* the far plane, z = 0 */
  21.  
  22. #define kRadius        5
  23.  
  24.  
  25. /* DrawCircle - draw a circle, centered at x, y. radius 
  26.  */
  27. static void DrawCircle(Integer x, Integer y){
  28.     Rect    r;
  29.  
  30.     r.left  = x - kRadius;
  31.     r.right = x + kRadius;
  32.     r.top   = y - kRadius;
  33.     r.bottom= y + kRadius;
  34.     PaintOval(&r);
  35. }
  36.  
  37.  
  38. /* ComputeAutoStereogram - See the October 1994 issue of Computer for more info.
  39.     Note: there is a bug in System 7.1 with the LaserWriter driver such that if
  40.         you CopyBits() to the printer, with an 8-bit indexed offscreen gworld
  41.         as the source, the first and last entries of the color table of the
  42.         offscreen gworld get set so the first is white and the last is black.
  43.         So, we follow that scheme in this program: for an 8-bit pixmap index,
  44.         the gray scale value is the complement of the index.
  45.         Watch out, expressions evaluate to ints in C, so ~(unsigned char) 1
  46.         if 0xFFFE not 0xFE
  47.  */
  48. OSErr ComputeAutoStereogram(GWorldPtr src, GWorldPtr dest, Boolean isGray){
  49.     OSErr            errCode;
  50.     Str255            buf;
  51.     CGrafPtr        savePort;
  52.     GDHandle        saveGD;
  53.     PixMapHandle    pmSrc;
  54.     PixMapHandle    pmDest;
  55.     LongInt            y, yMax;
  56.     LongInt            x, xMax, xMaxM1;
  57.     Integer            sameBuffer[512];
  58.     Integer            *same;
  59.     Integer            s;
  60.     Integer            left, right;
  61.     unsigned char    *srcP, *destP;
  62.     unsigned char    colorBuffer[512];
  63.     unsigned char    *color;
  64.     Boolean            visible;
  65.     LongInt            t;
  66.     float            z;
  67.     float            zt;
  68.     Integer            k;
  69.     
  70.     GetIndString(buf, kMainStrs, kComputingStereogramS);
  71.     SetProgressLabelText(buf);
  72.  
  73.     errCode = noErr;
  74.     same = NIL;
  75.     color = NIL;
  76.     GetGWorld(&savePort, &saveGD);
  77.     pmSrc = GetGWorldPixMap(src);
  78.     pmDest = GetGWorldPixMap(dest);
  79.     LockPixels(pmDest);
  80.     LockPixels(pmSrc);
  81.     SetGWorld(dest, NIL);
  82.  
  83.     yMax = src->portRect.bottom - src->portRect.top;
  84.     xMax = src->portRect.right - src->portRect.left;
  85.     xMaxM1 = xMax - 1;
  86.     if(xMax < 512){
  87.         same = sameBuffer;
  88.         color = colorBuffer;
  89.     }else{
  90.         if(NIL == (same = (Integer *) NewPtr(sizeof(Integer) * xMax))){
  91.             errCode = memFullErr;
  92.             goto errSkip;
  93.         }
  94.         if(NIL == (color = (unsigned char *) NewPtr(xMax))){
  95.             errCode = memFullErr;
  96.             goto errSkip;
  97.         }
  98.     }
  99.  
  100.     for(y = 0 ; y < yMax ; y++){
  101.         SetGWorld(savePort, saveGD);
  102.         if(noErr != (errCode = ShowProgress(y, yMax))){
  103.             goto errSkip;
  104.         }
  105.         SetGWorld(dest, NIL);
  106.         for(x = 0 ; x < xMax ; x++){
  107.             same[x] = x;                /* each pixel is initially linked ot itself */
  108.         }
  109.         srcP = (unsigned char *) GetPixBaseAddr(pmSrc) + y * ((**pmSrc).rowBytes & 0x7FFF);
  110.         destP = (unsigned char *) GetPixBaseAddr(pmDest) + y * ((**pmDest).rowBytes & 0x7FFF);
  111.         for(x = 0 ; x < xMax ; x++){
  112.             z = (0xFF & ~srcP[x])/255.0;
  113.             s = separation(z);
  114.             left = x - (s+(s&y&1))/2;
  115.             right = left + s;
  116.             if(0 <= left && right < xMax){
  117.                 t = 1;
  118.                 do{
  119.                     zt = z + 2*(2 - mu*z)*t/(mu*E);
  120.                     visible = (0xFF & ~srcP[x-t])/255.0 < zt && (0xFF & ~srcP[x+t])/255.0 < zt ;
  121.                     t++;
  122.                 }while(visible && zt < 1.0 && x-t > 0 && x+t < xMaxM1);
  123.                 if(visible){
  124.                     for(k = same[left] ; k != left && k != right ; k = same[left]){
  125.                         if(k < right){
  126.                             left = k;
  127.                         }else{
  128.                             left = right;
  129.                             right = k;
  130.                         }
  131.                     }
  132.                     same[left] = right;
  133.                 }
  134.             }
  135.         }
  136.         for( x = xMaxM1 ; x >= 0 ; x--){
  137.             if(same[x] == x){
  138.                 if(isGray){
  139.                     color[x] = (Random() & 0xFF);        /* free choice, do it randomly */
  140.                 }else{
  141.                     color[x] = (Random() & 1) ? 0x00 : 0xFF;    /* free choice, do it randomly */
  142.                 }
  143.             }else{
  144.                 color[x] = color[same[x]];                    /* constrained */
  145.             }
  146.             destP[x] = color[x];
  147.         }
  148.     }
  149.     DrawCircle(xMax/2 - farPlane/2, (yMax*19)/20);
  150.     DrawCircle(xMax/2 + farPlane/2, (yMax*19)/20);
  151. errSkip:
  152.     SetGWorld(savePort, saveGD);
  153.     ShowProgress(yMax, yMax);
  154.     if(same != sameBuffer && NIL != same){
  155.         DisposePtr((Ptr) same);
  156.     }
  157.     if(color != colorBuffer && NIL != color){
  158.         DisposePtr((Ptr) color);
  159.     }
  160.     UnlockPixels(pmSrc);
  161.     UnlockPixels(pmDest);
  162.     SetGWorld(savePort, saveGD);
  163.     return errCode;
  164. }
  165.  
  166.